import { ApiProperty } from '@nestjs/swagger'
import { PaginatedResponse } from 'src/common/models'

export class EventDTO {
  @ApiProperty({
    type: String,
    description:
      'The anonymous ID of the user. See [anonymousId](https://segment.com/docs/connections/spec/common/#anonymousid).',
    example: 'guest-1234567890',
    required: false,
  })
  anonymousId?: string
  context?: {
    active?: boolean
    app?: {
      name?: string
      version?: string
      build?: string
      namespace?: string
    }
    campaign?: {
      name?: string
      source?: string
      medium?: string
      term?: string
      content?: string
    }
    device?: {
      id?: string
      advertisingId?: string
      adTrackingEnabled?: boolean
      manufacturer?: string
      model?: string
      name?: string
      type?: string
      token?: string
    }
    ip?: string
    library?: {
      name?: string
      version?: string
    }
    locale?: string
    network?: {
      bluetooth?: boolean
      carrier?: string
      cellular?: boolean
      wifi?: boolean
    }
    os?: {
      name?: string
      version?: string
    }
    page?: {
      path?: string
      referrer?: string
      search?: string
      title?: string
      url?: string
    }
    referrer?: {
      id?: string
      type?: string
    }
    screen?: {
      width?: number
      height?: number
      density?: number
    }
    groupId?: string
    timezone?: string
    userAgent?: string
    userAgentData?: {
      brands?: {
        brand?: string
        version?: string
      }[]
      mobile?: boolean
      platform?: string
    }
  }
  integrations?: {
    All?: boolean
    Mixpanel?: boolean
    Salesforce?: boolean
  }
  @ApiProperty({
    type: String,
    description: 'The event name. Used only with `type: "track"`.',
    example: 'UserSignedUp',
    required: false,
  })
  event?: string
  messageId?: string
  receivedAt?: string
  sentAt?: string
  @ApiProperty({
    type: String,
    description: 'The timestamp of the event. Autogenerated if not provided.',
    example: '2021-01-01T00:00:00Z',
    required: false,
  })
  timestamp?: string
  @ApiProperty({
    type: String,
    description: 'The type of the event. Possible values: `page`, `track`, `identify`, `group`.',
    example: 'track',
    required: false,
  })
  type: 'page' | 'track' | 'identify' | 'group'
  @ApiProperty({
    type: String,
    description: 'The ID of the user.',
    example: 'user-1234567890',
    required: false,
  })
  userId?: string
  @ApiProperty({
    type: String,
    description: 'The ID of the group.',
    example: 'group-1234567890',
    required: false,
  })
  groupId?: string
  @ApiProperty({
    type: Object,
    description: 'The properties of the event. Only used with `type: "track"`.',
    example: {
      page: '/home',
      referrer: 'https://www.google.com',
    },
    required: false,
  })
  properties?: {
    [key: string]: any
  }
  @ApiProperty({
    type: Object,
    description: 'The traits of the user or group.',
    example: {
      email: 'john.doe@example.com',
      name: 'John Doe',
    },
    required: false,
  })
  traits?: {
    [key: string]: any
  }
  @ApiProperty({
    type: String,
    description:
      "Optional instance ID. Instance IDs are used to partition events by source. It is typically used for isolating data for the same customer. For instance, if you have a SaaS product, you may want to segment events by customer. In this case, you can set the instance ID to the customer's organizaiton ID.",
    example: 'customer-1234567890',
    required: false,
  })
  instanceId?: string
}

export class EventsDTO {
  @ApiProperty({
    type: [EventDTO],
    description: 'The events to insert.',
  })
  events: EventDTO[]
}
export class Event {
  @ApiProperty({
    type: String,
    description:
      'The anonymous ID of the user. See [anonymousId](https://segment.com/docs/connections/spec/common/#anonymousid).',
    example: 'guest-1234567890',
    required: false,
  })
  anonymousId?: string

  @ApiProperty({
    type: String,
    description: 'The UUID of the event.',
    example: '123e4567-e89b-12d3-a456-426614174000',
  })
  uuid: string

  @ApiProperty({
    type: String,
    description: 'The type of the event.',
    example: 'track',
    required: true,
  })
  type: string

  @ApiProperty({
    type: String,
    description: 'The event name.',
    example: 'User SignedUp',
    required: false,
  })
  event: string

  @ApiProperty({
    type: String,
    description: 'The user ID.',
    example: 'user-123',
    required: false,
  })
  userId?: string

  @ApiProperty({
    type: String,
    description: 'The group ID.',
    example: 'group-456',
    required: false,
  })
  groupId?: string

  @ApiProperty({
    type: Object,
    description: 'The properties of the event. Only used with `type: "track"`.',
    example: {
      page: '/home',
      referrer: 'https://www.google.com',
    },
    required: false,
  })
  properties?: {
    [key: string]: any
  }

  context?: Record<string, any>
  traits?: Record<string, any>

  @ApiProperty({
    type: Date,
    description: 'The timestamp of the event.',
    example: '2021-01-01T00:00:00Z',
  })
  timestamp: Date

  parsedAt: Date

  @ApiProperty({
    type: String,
    description:
      "Optional instance ID. Instance IDs are used to partition events by source. It is typically used for isolating data for the same customer. For instance, if you have a SaaS product, you may want to segment events by customer. In this case, you can set the instance ID to the customer's organizaiton ID.",
    example: 'customer-1234567890',
    required: false,
  })
  instanceId?: string
}

export class EventsQuery {
  @ApiProperty({
    type: String,
    description: 'The event name to filter by.',
    required: false,
    example: 'Created Account',
  })
  event?: string

  @ApiProperty({
    type: String,
    description: 'The UUID to filter by.',
    required: false,
    example: '123e4567-e89b-12d3-a456-426614174000',
  })
  uuid?: string

  @ApiProperty({
    type: String,
    description: 'The user ID to filter by.',
    required: false,
    example: 'user-123',
  })
  userId?: string

  @ApiProperty({
    type: String,
    description: 'The group ID to filter by.',
    required: false,
    example: 'group-456',
  })
  groupId?: string

  @ApiProperty({
    type: String,
    description: 'The anonymous ID to filter by.',
    required: false,
    example: 'anon-789',
  })
  anonymousId?: string

  @ApiProperty({
    type: String,
    description: 'The instance ID to filter by.',
    required: false,
    example: 'instance-101112',
  })
  instanceId?: string

  @ApiProperty({
    type: Object,
    description: 'The properties to filter by.',
    required: false,
    example: { key: 'value' },
  })
  properties?: Record<string, any>

  @ApiProperty({
    type: Object,
    description: 'The traits to filter by.',
    required: false,
    example: { key: 'value' },
  })
  traits?: Record<string, any>

  @ApiProperty({
    type: Object,
    description: 'The context to filter by.',
    required: false,
    example: { key: 'value' },
  })
  context?: Record<string, any>

  @ApiProperty({
    type: String,
    description: 'The start date to filter by.',
    required: false,
    example: '2022-01-01T00:00:00Z',
  })
  startDate?: string

  @ApiProperty({
    type: String,
    description: 'The end date to filter by.',
    required: false,
    example: '2022-12-31T23:59:59Z',
  })
  endDate?: string

  @ApiProperty({
    type: Number,
    description: 'The limit of records to return.',
    required: false,
    example: 100,
  })
  limit?: number

  @ApiProperty({
    type: Number,
    description: 'The offset of records to return.',
    required: false,
    example: 0,
  })
  offset?: number

  @ApiProperty({
    type: String,
    description: 'The field to order by.',
    required: false,
    example: 'timestamp',
  })
  orderByField?: string

  @ApiProperty({
    type: String,
    enum: ['ASC', 'DESC'],
    description: 'The direction to order by.',
    required: false,
    example: 'ASC',
  })
  orderByDirection?: 'ASC' | 'DESC'
}

export class PaginatedEventResponse extends PaginatedResponse<Event> {
  @ApiProperty({
    type: [Event],
    description: 'The events found based on the query.',
    example: [
      {
        uuid: '123',
        type: 'track',
        event: 'user_signed_up',
        userId: 'user-123',
        groupId: 'group-456',
        anonymousId: 'anon-789',
        instanceId: 'instance-101112',
        properties: {
          key: 'value',
        },
      },
    ],
  })
  results: Event[]
}
